package com.git.smp.utils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class EBCDICTransUtil
{
  public static final String GBK = "GBK";
  public static final String UTF8 = "utf-8";
  private static int TFP = 1;
  private static int TTP = 2;
  private static int FFP = 3;

  private static int Service = FFP;

  private static final int[][] Gbc_Offset = { 
    { 41377, 16448 }, 
    { 41633, 17841 }, { 41889, 16986 }, 
    { 42145, 17479 }, { 42401, 17223 }, { 42657, 16737 }, 
    { 42913, 16832 }, { 43169, 17985 }, { 43428, 18084 } };

  private static final int[][] Gbc_To_Ebc = { { 
    16448, 17220, 17217, 17221, 17733, 17734, 17504, 17499, 
    17501, 17482, 17313, 17532, 17535, 17505, 17521, 17506, 
    17522, 17507, 17523, 17508, 17524, 17509, 17525, 17218, 
    17219, 17474, 17475, 17755, 17756, 17510, 17526, 17483, 
    17530, 17531, 17762, 17763, 17764, 17765, 17766, 17767, 
    17768, 17769, 17770, 17771, 17772, 17773, 17774, 17775, 
    17776, 17777, 17778, 17779, 17780, 17781, 17782, 17783, 
    17484, 17785, 17786, 17511, 17527, 17485, 17528, 17512, 
    17513, 17529, 17645, 17646, 17647, 17486, 17120, 17800, 
    17226, 16970, 17803, 17514, 17518, 17637, 17638, 17632, 
    17633, 17636, 17639, 17640, 17641, 17642, 17634, 17635, 
    17515, 17648, 17649, 17650, 17651, 17533 }, 
    { 17825, 17826, 17827, 17828, 17829, 17830, 17831, 17832, 
    17833, 17834, 17835, 17836, 17837, 17838, 17839, 17840, 
    17841, 17842, 17843, 17844, 17845, 17846, 17847, 17848, 
    17849, 17850, 17851, 17836, 17853, 17854, 17855, 17856, 
    17857, 17858, 17859, 17860, 17861, 17862, 17863, 17864, 
    17865, 17866, 17867, 17868, 17869, 17886, 17887, 17872, 
    17873, 17874, 17875, 17876, 17877, 17878, 17879, 17880, 
    17889, 17890, 17891, 17892, 17893, 17894, 17895, 17896, 
    17897, 17898, 17905, 17906, 17907, 17908, 17909, 17910, 
    17911, 17912, 17913, 17914, 16881, 16882, 16883, 16884, 
    16885, 16886, 16887, 16888, 16889, 16890, 16891, 16892 }, 
    { 16986, 17023, 17019, 16987, 17004, 16976, 17488, 16973, 
    16989, 16988, 16974, 17003, 16992, 16971, 16993, 17136, 
    17137, 17138, 17139, 17140, 17141, 17142, 17143, 17144, 
    17145, 17018, 16990, 16972, 17022, 17006, 17007, 17020, 
    17089, 17090, 17091, 17092, 17093, 17094, 17095, 17096, 
    17097, 17105, 17106, 17107, 17108, 17109, 17110, 17111, 
    17112, 17113, 17122, 17123, 17124, 17125, 17126, 17127, 
    17128, 17129, 17476, 17376, 17477, 17520, 17005, 17017, 
    17025, 17026, 17027, 17028, 17029, 17030, 17031, 17032, 
    17033, 17041, 17042, 17043, 17044, 17045, 17046, 17047, 
    17048, 17049, 17058, 17059, 17060, 17061, 17062, 17063, 
    17064, 17065, 17088, 16975, 17104, 17057 }, 
    { 17479, 17537, 17480, 17538, 17481, 17539, 17489, 17540, 
    17490, 17541, 17542, 17600, 17543, 17601, 17544, 17602, 
    17545, 17603, 17546, 17604, 17548, 17605, 17549, 17606, 
    17550, 17607, 17551, 17608, 17552, 17609, 17553, 17610, 
    17554, 17611, 17494, 17555, 17612, 17556, 17613, 17557, 
    17614, 17558, 17559, 17560, 17561, 17562, 17565, 17615, 
    17621, 17566, 17616, 17622, 17567, 17617, 17623, 17570, 
    17618, 17624, 17571, 17619, 17625, 17572, 17573, 17574, 
    17575, 17576, 17491, 17577, 17492, 17578, 17493, 17580, 
    17581, 17582, 17583, 17594, 17595, 17495, 17596, 17626, 
    17478, 17597 }, 
    { 17223, 17281, 17224, 17282, 17225, 17283, 17233, 17284, 
    17234, 17285, 17286, 17344, 17287, 17345, 17288, 17346, 
    17289, 17347, 17290, 17348, 17292, 17349, 17293, 17350, 
    17294, 17351, 17295, 17352, 17296, 17353, 17297, 17354, 
    17298, 17355, 17238, 17299, 17356, 17300, 17357, 17301, 
    17358, 17302, 17303, 17304, 17305, 17306, 17309, 17359, 
    17365, 17310, 17360, 17366, 17311, 17361, 17367, 17314, 
    17362, 17368, 17315, 17363, 17369, 17316, 17317, 17318, 
    17319, 17320, 17235, 17321, 17236, 17322, 17237, 17324, 
    17325, 17326, 17327, 17338, 17339, 17239, 17340, 17370, 
    17371, 17222, 17341, 17364, 17241, 17242 } };

  private static final int[] Asc_To_Ebc = { 0, 1, 2, 3, 55, 
    45, 46, 47, 22, 5, 21, 11, 12, 13, 14, 15, 
    16, 17, 18, 19, 93, 61, 50, 38, 24, 25, 63, 
    39, 34, 29, 30, 31, 64, 90, 127, 123, 224, 108, 
    80, 125, 77, 93, 92, 78, 107, 96, 75, 97, 240, 
    241, 242, 243, 244, 245, 246, 247, 248, 249, 122, 94, 
    76, 126, 110, 111, 124, 193, 194, 195, 196, 197, 198, 
    199, 200, 201, 209, 210, 211, 212, 213, 214, 215, 216, 
    217, 226, 227, 228, 229, 230, 231, 232, 233, 186, 178, 
    187, 95, 109, 121, 129, 130, 131, 132, 133, 134, 135, 
    136, 137, 145, 146, 147, 148, 149, 150, 151, 152, 153, 
    162, 163, 164, 165, 166, 167, 168, 169, 192, 79, 208, 
    161, 7 };

  private static final int[] Ebc_Offset = { 16448, 16705, 16970, 17217, 
    17474, 17733, 17985 };

  private static final int[][] Ebc_To_Gbc = { 
    { 41377 }, 
    { 42689, 42690, 42691, 42692, 42693, 42694, 42695, 42696, 
    42697, 42698, 42699, 42700, 42701, 42702, 42703, 
    42704, 42705, 42706, 42707, 42708, 42709, 42710, 
    42711, 42712, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 42657, 42658, 42659, 42660, 
    42661, 42662, 42663, 42664, 42665, 42666, 42667, 
    42668, 42669, 42670, 42671, 42672, 42673, 42674, 
    42675, 42676, 42677, 42678, 42679, 42680, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 42961, 
    42962, 42963, 42964, 42965, 42966, 42967, 42968, 
    42969, 42970, 42971, 42972, 42973, 42974, 42975, 
    42976, 42977, 42978, 42979, 42980, 42981, 42982, 
    42983, 42984, 42985, 42986, 42987, 42988, 42989, 
    42990, 42991, 42992, 42993, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    42913, 42914, 42915, 42916, 42917, 42918, 42919, 
    42920, 42921, 42922, 42923, 42924, 42925, 42926, 
    42927, 42928, 42929, 42930, 42931, 42932, 42933, 
    42934, 42935, 42936, 42937, 42938, 42939, 42940, 
    42941, 42942, 42943, 42944, 42945, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41697, 41714, 41715, 41716, 41717, 41718, 41719, 
    41720, 41721, 41722, 41723, 41724 }, 
    { 41450, 41902, 41916, 41896, 41899, 41964, 41894, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41889, 41892, 41898, 41897, 41915, 41377, 
    41901, 41903, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41900, 41893, 41951, 
    41918, 41919, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41952, 41914, 41891, 
    41920, 41377, 41917, 41890, 41377, 41937, 41938, 
    41939, 41940, 41941, 41942, 41943, 41944, 41945, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41946, 41947, 41948, 41949, 41950, 41951, 41952, 
    41953, 41954, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41966, 41955, 41956, 41957, 41958, 
    41959, 41960, 41961, 41962, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41963, 41921, 
    41922, 41923, 41924, 41925, 41926, 41927, 41928, 
    41929, 41377, 41377, 41377, 41377, 41377, 41377, 
    41965, 41930, 41931, 41932, 41933, 41934, 41935, 
    41936, 41937, 41938, 41377, 41377, 41377, 41377, 
    41377, 41377, 41447, 41377, 41939, 41940, 41941, 
    41942, 41943, 41944, 41945, 41946, 41377, 41377, 
    41377, 41377, 41377, 41377, 41904, 41905, 41906, 
    41907, 41908, 41909, 41910, 41911, 41912, 41913 }, 
    { 41379, 41400, 41401, 41378, 41380, 42482, 42401, 42403, 
    42405, 41449, 41377, 41377, 41377, 41377, 41377, 
    41377, 42407, 42409, 42467, 42469, 42471, 42435, 
    42478, 41377, 42485, 42486, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    42402, 42404, 42406, 42408, 42410, 42411, 42413, 
    42415, 42417, 42419, 41377, 42421, 42423, 42425, 
    42427, 42429, 42431, 42433, 42436, 42438, 42440, 
    42442, 42443, 42444, 42445, 42446, 41377, 41377, 
    42447, 42450, 42453, 41377, 41387, 42456, 42459, 
    42462, 42463, 42464, 42465, 42466, 42468, 42470, 
    41377, 42472, 42473, 42474, 42475, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 42476, 42477, 42479, 42483, 41377, 41377, 
    42412, 42414, 42416, 42418, 42420, 42422, 42424, 
    42426, 42428, 42430, 42432, 42434, 42437, 42439, 
    42441, 42448, 42451, 42454, 42457, 42460, 42484, 
    42449, 42452, 42455, 42458, 42461, 42480, 42481, 
    41377, 41377, 41377, 41377, 41948 }, 
    { 41402, 41403, 41947, 41949, 42225, 42145, 42147, 42149, 
    41386, 41408, 41433, 41438, 41446, 41377, 41895, 
    42151, 42153, 42211, 42213, 42215, 42179, 42222, 
    41377, 41377, 41377, 41384, 41377, 41385, 41377, 
    41377, 41383, 41390, 41392, 41394, 41396, 41398, 
    41406, 41436, 41440, 41441, 41452, 41465, 41377, 
    41377, 41453, 41377, 41950, 41391, 41393, 41395, 
    41397, 41399, 41407, 41437, 41439, 41442, 41409, 
    41410, 41388, 41470, 41377, 41389, 41377, 42146, 
    42148, 42150, 42152, 42154, 42155, 42157, 42159, 
    42161, 42163, 41377, 42165, 42167, 42169, 42171, 
    42173, 42175, 42177, 42180, 42182, 42184, 42186, 
    42187, 42188, 42189, 42190, 41377, 41377, 42191, 
    42194, 42197, 41377, 41377, 42200, 42203, 42206, 
    42207, 42208, 42209, 42210, 42212, 42214, 41377, 
    42216, 42217, 42218, 42219, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    42220, 42221, 42223, 42226, 41377, 41377, 42156, 
    42158, 42160, 42162, 42164, 42166, 42168, 42170, 
    42172, 42174, 42176, 42178, 42181, 42183, 42185, 
    42192, 42195, 42198, 42201, 42204, 41377, 42193, 
    42196, 42199, 42202, 42205, 42224, 41377, 41377, 
    41377, 41377, 41377, 41456, 41457, 41463, 41464, 
    41458, 41454, 41455, 41459, 41460, 41461, 41462, 
    41377, 41377, 41443, 41444, 41445, 41466, 41467, 
    41468, 41469 }, 
    { 41381, 41382, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41404, 41405, 41377, 41377, 41377, 41377, 41377, 
    41411, 41412, 41413, 41414, 41415, 41416, 41417, 
    41418, 41419, 41420, 41421, 41422, 41423, 41424, 
    41425, 41426, 41427, 41428, 41429, 41430, 41431, 
    41432, 41377, 41434, 41435, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41448, 41377, 41377, 41451, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41660, 41377, 41377, 
    41377, 41377, 41649, 41650, 41651, 41652, 41653, 
    41654, 41655, 41656, 41657, 41658, 41659, 41377, 
    41661, 41662, 41663, 41664, 41665, 41666, 41667, 
    41668, 41669, 41670, 41671, 41672, 41673, 41674, 
    41675, 41676, 41677, 41377, 41377, 41680, 41681, 
    41682, 41683, 41684, 41685, 41686, 41687, 41688, 
    41377, 41377, 41377, 41377, 41377, 41678, 41679, 
    41377, 41689, 41690, 41691, 41692, 41693, 41694, 
    41695, 41696, 41697, 41698, 41377, 41377, 41377, 
    41377, 41377, 41377, 41701, 41702, 41703, 41704, 
    41705, 41706, 41707, 41708, 41709, 41710 }, 
    { 43169, 43170, 43171, 43172, 43173, 43174, 43175, 43176, 
    43177, 43178, 43179, 43180, 43181, 43182, 43183, 
    43184, 43185, 43186, 43187, 43188, 43189, 43190, 
    43191, 43192, 43193, 43194, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    43205, 43206, 43207, 43208, 43209, 43210, 43211, 
    43212, 43213, 43214, 43215, 43216, 43217, 43218, 
    43219, 43220, 43221, 43222, 43223, 43224, 43225, 
    43226, 43227, 43228, 43229, 43230, 43231, 43232, 
    43233, 43234, 43235, 43236, 43237, 43238, 43239, 
    43240, 43241, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    41377, 41377, 41377, 41377, 41377, 41377, 41377, 
    43428, 43429, 43430, 43431, 43432, 43433, 43434, 
    43435, 43436, 43437, 43438, 43439, 43440, 43441, 
    43442, 43443, 43444, 43445, 43446, 43447, 43448, 
    43449, 43450, 43451, 43452, 43453, 41377, 43455, 
    43456, 43457, 43458, 43459, 43460, 43461, 43462, 
    43463, 43464, 43465, 43466, 43467, 43468, 43469, 
    43470, 43471, 41377, 43473, 43474, 43475, 43476, 
    43477, 43478, 43479, 43480, 43481, 43482, 43483, 
    43484, 43485, 43486, 43487, 43488, 43489, 43490, 
    43491, 43492, 43493, 43494, 43495, 43496, 43497, 
    43498, 43499, 43500, 43501, 43502, 43503 } };

  private static final int[] Ebc_To_Asc = { 0, 1, 2, 3, 32, 
    9, 32, 127, 32, 32, 32, 11, 12, 13, 14, 15, 
    16, 17, 18, 19, 32, 10, 8, 32, 24, 25, 32, 
    32, 28, 29, 30, 31, 32, 32, 32, 32, 32, 10, 
    23, 27, 32, 32, 32, 32, 32, 5, 6, 7, 32, 
    32, 22, 32, 32, 32, 32, 4, 32, 32, 32, 32, 
    20, 21, 32, 26, 32, 16, 17, 18, 19, 20, 21, 
    22, 23, 24, 91, 46, 60, 40, 43, 124, 38, 32, 
    32, 32, 32, 32, 32, 32, 32, 32, 33, 36, 42, 
    41, 59, 94, 45, 47, 32, 32, 32, 32, 32, 32, 
    32, 32, 124, 44, 37, 95, 62, 63, 32, 32, 32, 
    32, 32, 32, 32, 32, 32, 96, 58, 35, 64, 39, 
    61, 34, 32, 97, 98, 99, 100, 101, 102, 103, 104, 
    105, 32, 32, 32, 32, 32, 32, 32, 106, 107, 108, 
    109, 110, 111, 112, 113, 114, 32, 32, 32, 32, 32, 
    32, 32, 126, 115, 116, 117, 118, 119, 120, 121, 122, 
    32, 32, 32, 32, 32, 32, 32, 32, 92, 32, 32, 
    32, 32, 32, 32, 32, 91, 93, 32, 32, 32, 32, 
    123, 65, 66, 67, 68, 69, 70, 71, 72, 73, 32, 
    32, 32, 32, 32, 32, 125, 74, 75, 76, 77, 78, 
    79, 80, 81, 82, 32, 32, 32, 32, 32, 32, 36, 
    32, 83, 84, 85, 86, 87, 88, 89, 90, 32, 32, 
    32, 32, 32, 32, 48, 49, 50, 51, 52, 53, 54, 
    55, 56, 57, 32, 32, 32, 32, 32, 32 };

  private static int HIBYTE(int x)
  {
    return x >> 8 & 0xFF;
  }

  private static int LOBYTE(int x) {
    return x & 0xFF;
  }

  public static byte[] ASIICtoEBCDIC(byte[] in_buf)
  {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    int j = 0;
    int k = 0;
    boolean DBCS_Flag = false;
    for (int i = 0; i < in_buf.length; i++) {
      if ((in_buf[i] & 0xFF) >= 161)
      {
        if (!DBCS_Flag)
        {
          out.write(14);
          DBCS_Flag = true;
        }
        k = (in_buf[i] & 0xFF) - 161;
        switch (in_buf[i]) {
        case -95:
        case -94:
        case -93:
        case -92:
        case -91:
          j = (in_buf[i] & 0xFF) * 256 + (in_buf[(i + 1)] & 0xFF) - 
            Gbc_Offset[k][0];
          out.write((byte)HIBYTE(Gbc_To_Ebc[k][j]));
          out.write((byte)LOBYTE(Gbc_To_Ebc[k][j]));
          break;
        case -90:
        case -88:
        case -87:
          j = (in_buf[i] & 0xFF) * 256 + (in_buf[(i + 1)] & 0xFF) - 
            Gbc_Offset[k][0];
          out.write((byte)HIBYTE(Gbc_Offset[k][1] + j));
          out.write((byte)LOBYTE(Gbc_Offset[k][1] + j));
          break;
        case -89:
          out.write(65);
          if ((in_buf[(i + 1)] & 0xFF) >= 209)
            out.write((byte)((in_buf[(i + 1)] & 0xFF) - 81));
          else
            out.write((byte)((in_buf[(i + 1)] & 0xFF) + 31));
          break;
        default:
          if (1 == (in_buf[i] & 0xFF) % 2) {
            out.write((byte)(((in_buf[i] & 0xFF) + 1) / 2 - 16));
            if ((in_buf[(i + 1)] & 0xFF) > 223)
              out.write((byte)((in_buf[(i + 1)] & 0xFF) - 95));
            else
              out.write((byte)((in_buf[(i + 1)] & 0xFF) - 96));
          } else {
            out.write((byte)((in_buf[i] & 0xFF) / 2 - 16));
            out.write((byte)((in_buf[(i + 1)] & 0xFF) - 1));
          }break;
        }
        i++;
      }
      else {
        if (DBCS_Flag) {
          out.write(15);
          DBCS_Flag = false;

          if ((Service == TFP) || (Service == TTP)) {
            i += 2;
          }
        }
        if ((in_buf[i] & 0xFF) >= 161)
        {
          i--;
        } else if ((in_buf[i] != 10) && 
          (in_buf[i] != 13)) {
          out.write((byte)Asc_To_Ebc[in_buf[i]]);
        }
      }
    }
    if (DBCS_Flag)
      out.write(15);
    byte[] out_buf = out.toByteArray();
    try {
      out.close();
    } catch (IOException localIOException) {
    }
    return out_buf;
  }

  public static byte[] EBCDICtoASIIC(byte[] in_buf)
  {
    int k = 0;
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    boolean DBCS_Flag = false;

    for (int i = 0; i < in_buf.length; i++) {
      if ((in_buf[i] & 0xFF) == 14) {
        DBCS_Flag = true;
      }
      else if ((in_buf[i] & 0xFF) == 15)
      {
        if ((Service == TFP) || (Service == TTP)) {
          out.write(32);
          out.write(32);
        }

        DBCS_Flag = false;
      }
      else if (DBCS_Flag) {
        k = (in_buf[i] & 0xFF) - 64;
        switch (in_buf[i]) {
        case 64:
        case 65:
        case 66:
        case 67:
        case 68:
        case 69:
        case 70:
          int j = (in_buf[i] & 0xFF) * 256 + (in_buf[(i + 1)] & 0xFF) - Ebc_Offset[k];
          out.write((byte)HIBYTE(Ebc_To_Gbc[k][j]));
          out.write((byte)LOBYTE(Ebc_To_Gbc[k][j]));
          break;
        default:
          if ((in_buf[(i + 1)] & 0xFF) >= 160) {
            out.write((byte)(in_buf[i] & 0xFF) * 2 + 32);
            out.write((byte)((in_buf[(i + 1)] & 0xFF) + 1));
          }
          else if ((in_buf[(i + 1)] & 0xFF) > 127) {
            out.write((byte)((in_buf[i] & 0xFF) * 2 + 31));
            out.write((byte)((in_buf[(i + 1)] & 0xFF) + 95));
          }
          else
          {
            out.write((byte)((in_buf[i] & 0xFF) * 2 + 31));
            out.write((byte)((in_buf[(i + 1)] & 0xFF) + 96));
          }
          break;
        }

        i++;
      }
      else {
        out.write((byte)Ebc_To_Asc[(in_buf[i] & 0xFF)]);
      }
    }

    out.write(0);

    byte[] out_buf = out.toByteArray();
    try {
      out.close();
    }
    catch (IOException localIOException) {
    }
    return out_buf;
  }
}